

#include <cegame/cexmlmaterialloader.h>
#include <cegfx/cematerialmanager.h>
#include <cexml/cexml.h>


ceXMLMaterialLoader::ceXMLMaterialLoader()
{
}

bool ceXMLMaterialLoader::CanLoad (iFile* file) const
{
	ceString ext = file->GetExtension ();
	if (ext == "xml")
	{
		return true;
	}
	return false;
}

ceString ceXMLMaterialLoader::LoadName (iFile* file)
{
	ceXmlDocument doc;
	if (!doc.Open (file))
	{
		return "";
	}

	ceXmlElement root = doc.GetRootElement ();
	if (root.GetTagName () != "material")
	{
		// don't match the format?
		return "";
	}

	return root.GetAttribute ("name");
}

ceMaterial* ceXMLMaterialLoader::Load (LPDIRECT3DDEVICE9 device, iFile* file)
{
	ceXmlDocument doc;
	if (!doc.Open (file))
	{
		return 0;
	}

	ceXmlElement root = doc.GetRootElement ();
	if (root.GetTagName () != "material")
	{
		// don't match the format?
		return 0;
	}

	ceXmlElement elemData = root.GetChild ("data");
	ceXmlElement elemMaps = root.GetChild ("maps");

	if (!elemData.IsValid() || !elemMaps.IsValid ())
	{
		return 0;
	}

	ceMaterialManager* mgr = ceMaterialManager::Get();
	ceMaterial* material = new ceMaterial ();

	// scan all data that is needed for the material
	for (unsigned i=0, j=elemData.GetNumberOfChildren (); i<j; i++)
	{
		ceXmlElement dataValueElem = elemData.GetChild (i);
		if (dataValueElem.GetTagName () == "effect")
		{
			if (	!dataValueElem.HasAttribute ("name") 
				||	!dataValueElem.HasAttribute ("filename"))
			{
				printf ("Malformed XML-Material description: %s\n", file->GetName ().c_str ());
				delete material;
				return 0;
			}
				  
			ceString name = dataValueElem.GetAttribute ("name");
			ceString filename = dataValueElem.GetAttribute ("filename");
			mgr->RegisterEffect (name, filename);
		}
		else if (dataValueElem.GetTagName () == "texture")
		{
			if (	!dataValueElem.HasAttribute ("name") 
				||	!dataValueElem.HasAttribute ("filename"))
			{
				printf ("Malformed XML-Material description: %s\n", file->GetName ().c_str ());
				delete material;
				return 0;
			}
				  
			ceString name = dataValueElem.GetAttribute ("name");
			ceString filename = dataValueElem.GetAttribute ("filename");
			mgr->RegisterTexture (name, filename);
		}
	}

	// now map all the data that is needed for the material 
	for (unsigned i=0, j=elemMaps.GetNumberOfChildren (); i<j; i++)
	{
		ceXmlElement elemMapValue = elemMaps.GetChild (i);
		if (!elemMapValue.HasAttribute ("name"))
		{
			printf ("Malformed XML-Material description: %s\n", file->GetName ().c_str ());
			delete material;
			return 0;
		}

		ceString name = elemMapValue.GetAttribute ("name");
		ceString tag = elemMapValue.GetTagName ();
		if (tag == "effect")
		{
			material->SetEffect (mgr->GetEffect (name));
		}
		else if (tag == "diffuse")
		{
			material->SetDiffuseTexture (mgr->GetTexture (name));
		}
		else if (tag == "specular")
		{
			material->SetSpecularTexture (mgr->GetTexture (name));
		}
		else if (tag == "bump")
		{
			material->SetBumpTexture (mgr->GetTexture (name));
		}
		else
		{
			printf ("unknown mapping %s in %s\n", tag.c_str (), file->GetName ().c_str ());
		}
	}

	return material;
}
